package com.addplus.townmall.server.queue.serviceimpl;

import cn.binarywang.tools.generator.bank.BankCardNumberGenerator;
import com.addplus.townmall.server.api.constant.ErrorCode;
import com.addplus.townmall.server.api.constant.StringConstant;
import com.addplus.townmall.server.api.exception.ErrorException;
import com.addplus.townmall.server.api.mapper.town.GiftBatchCardMapper;
import com.addplus.townmall.server.api.mapper.town.GiftCardMapper;
import com.addplus.townmall.server.api.model.town.GiftBatchCard;
import com.addplus.townmall.server.api.model.town.GiftCard;
import com.addplus.townmall.server.api.model.town.param.GiftBatchCardParam;
import com.addplus.townmall.server.api.service.queue.GiftCardBatchService;
import com.addplus.townmall.server.api.utils.DataUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.Charset;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 类名: GiftCardBatchService
 *
 * @author zhangjiehang
 * @version V1.0
 * @date 2018/11/23 10:22 PM
 * @description 类描述: 礼品卡批量生产实现类
 */
@Service(interfaceClass = GiftCardBatchService.class, async = true)
public class GiftCardBatchServiceImpl extends ServiceImpl<GiftBatchCardMapper, GiftBatchCard> implements GiftCardBatchService {

    @Autowired
    private GiftCardMapper giftCardMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean giftCardBatchAccount(GiftBatchCardParam giftBatchCardParam) throws Exception {
        if (giftBatchCardParam == null || DataUtils.EmptyOrNegative(giftBatchCardParam.getGiftCardId(), giftBatchCardParam.getGiftCardTypeId(), giftBatchCardParam.getIsDeadline(), giftBatchCardParam.getCreateNumber(), giftBatchCardParam.getModifyUser()) || DataUtils.isEmpty(giftBatchCardParam.getGiftBatch())) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        if (giftBatchCardParam.getIsDeadline() == 1) {
            if (giftBatchCardParam.getStartDate() == null || giftBatchCardParam.getEndDate() == null) {
                throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
            }
            LocalDate localDate = LocalDate.now();
            if (localDate.isAfter(giftBatchCardParam.getStartDate()) || giftBatchCardParam.getStartDate().isAfter(giftBatchCardParam.getEndDate())) {
                throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
            }
        }
        if (giftBatchCardParam.getCreateNumber() > 1000) {
            throw new ErrorException(ErrorCode.SYS_ERROR_PARAM);
        }
        QueryWrapper<GiftCard> queryWrapper = new QueryWrapper<GiftCard>();
        queryWrapper.eq("is_delete", 0);
        queryWrapper.eq("id", giftBatchCardParam.getGiftCardId());
        GiftCard giftCard = giftCardMapper.selectOne(queryWrapper);
        if (giftCard == null) {
            throw new ErrorException(ErrorCode.REST_GIFT_CARD_SELECT_NULL);
        }
        //查询对应礼品卡
        List<GiftBatchCard> giftBatchCards = new ArrayList<>();
        List<String> giftCardAccount = new ArrayList<>();
        Long prefixAccount = null;
        if (redisTemplate.hasKey(StringConstant.GIFT_CARD_BATCH_CREATE_ACCOUNT)) {
            prefixAccount = redisTemplate.opsForValue().increment(StringConstant.GIFT_CARD_BATCH_CREATE_ACCOUNT, 1);
        } else {
            prefixAccount = redisTemplate.opsForValue().increment(StringConstant.GIFT_CARD_BATCH_CREATE_ACCOUNT, 100);
        }
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("UTF-8")), giftBatchCardParam.getCreateNumber(), 0.0001);
        for (int i = 0; i < giftBatchCardParam.getCreateNumber(); i++) {
            String account = BankCardNumberGenerator.generateByPrefix(prefixAccount.intValue());
            if (bloomFilter.mightContain(account)) {
                i--;
                continue;
            }
            if (bloomFilter.put(account)) {
                giftCardAccount.add(account);
            }
        }
        Long prefixPassWord = null;
        if (redisTemplate.hasKey(StringConstant.GIFT_CARD_BATCH_CREATE_PASSWORD)) {
            prefixPassWord = redisTemplate.opsForValue().increment(StringConstant.GIFT_CARD_BATCH_CREATE_PASSWORD, 1);
        } else {
            prefixPassWord = redisTemplate.opsForValue().increment(StringConstant.GIFT_CARD_BATCH_CREATE_PASSWORD, 10);
        }
        BloomFilter<String> bloomFilterPassWord = BloomFilter.create(Funnels.stringFunnel(Charset.forName("UTF-8")), giftBatchCardParam.getCreateNumber(), 0.0001);
        List<String> giftPassWord = new ArrayList<>();
        for (int i = 0; i < giftBatchCardParam.getCreateNumber(); i++) {
            String passWord = prefixPassWord.intValue() + this.codeUtil();
            if (bloomFilterPassWord.mightContain(passWord)) {
                i--;
                continue;
            }
            if (bloomFilterPassWord.put(passWord)) {
                giftPassWord.add(passWord);
            }
        }
        if (giftPassWord.size() != giftCardAccount.size() && giftPassWord.size() > 0 && giftCardAccount.size() > 0) {
            throw new ErrorException(ErrorCode.REST_GIFT_CARD_BATCH);
        }
        Date date = new Date();
        //插入数据库
        for (int i = 0; i < giftCardAccount.size(); i++) {
            GiftBatchCard giftBatchCard = new GiftBatchCard();
            giftBatchCard.setGiftCardTypeId(giftCard.getGiftCardTypeId());
            giftBatchCard.setGiftCardId(giftCard.getId());
            giftBatchCard.setGiftStatus(0);
            giftBatchCard.setGiftBatch(giftBatchCardParam.getGiftBatch());
            giftBatchCard.setGiftAccount(giftCardAccount.get(i));
            giftBatchCard.setGiftPassword(giftPassWord.get(i));
            giftBatchCard.setGiftCardName(giftCard.getGiftCardName());
            giftBatchCard.setIsDeadline(giftBatchCardParam.getIsDeadline());
            giftBatchCard.setGiftValue(giftCard.getGiftValue());
            if (giftBatchCardParam.getIsDeadline() == 1) {
                giftBatchCard.setStartDate(giftBatchCardParam.getStartDate());
                giftBatchCard.setEndDate(giftBatchCardParam.getEndDate());
            }
            giftBatchCard.setIsDelete(0);
            giftBatchCard.setGmtCreate(date);
            giftBatchCard.setGmtModified(date);
            giftBatchCard.setModifyUser(giftBatchCardParam.getModifyUser());
            giftBatchCards.add(giftBatchCard);
        }
        boolean isSuccess = this.saveBatch(giftBatchCards);
        return isSuccess;
    }


    private final static String passWordStr = "0123456789";

    /**
     * 方法描述：生成4位随机数
     *
     * @throws Exception
     * @author zhangjiehang
     * @date 2018/11/24 12:56 AM
     */
    private String codeUtil() {
        StringBuilder stringBuilder = new StringBuilder(4);
        for (int i = 0; i < 4; i++) {
            char ch = passWordStr.charAt(new Random().nextInt(passWordStr.length()));
            stringBuilder.append(ch);
        }
        return stringBuilder.toString();
    }


}
